package com.nz2004.smsplatform.strategy.service.impl;


import com.nz2004.smsplatform.common.constants.CacheConstants;
import com.nz2004.smsplatform.common.constants.StrategyConstants;
import com.nz2004.smsplatform.common.index.StandardSubmit;
import com.nz2004.smsplatform.strategy.service.FilterChain;
import com.nz2004.smsplatform.strategy.service.api.CacheService;
import com.nz2004.smsplatform.strategy.util.PushMessageUtil;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Set;

/**
 * @author ReJoice
 */
@Service(value = "limit")
@Slf4j
public class LimitStrategy implements FilterChain {

    @Resource
    private CacheService cacheService;

//    public static void main(String[] args) {
//        System.out.println(System.currentTimeMillis() - 60 *30 *1000);
//    }

    @Autowired
    private PushMessageUtil pushMessage;

    @Override
    public boolean strategy(StandardSubmit submit) {
        log.info("【限流策略】 限流策略执行了....");
        // TODO 在网关模块调用运营商发送短信成功后,存储数据到ZSet结构中,指定Key为前缀加手机号,score为当前系统时间的毫秒值,member无所谓

        // TODO 三个时间范围的查询分开写,实现动态可插拔.写三个LimitStrategy策略对象
        // 30s一条短信
        String key = CacheConstants.CACHE_PREFIX_SMS_LIMIT + submit.getDestMobile();
        //1. 获取当前系统时间
        double timeMillis = System.currentTimeMillis();
        System.out.println(System.currentTimeMillis());
        //2. 获取30s前的系统时间
        double thirtySecond = timeMillis - 30 * 1000;
        //3. 调用cache模块的zRangeByScore命令,查询结果即可. 获取30s内的数据
        Set<Object> set = cacheService.zRangeByScore(key,thirtySecond,timeMillis);
        //4. 结果长度大于等于1,限流策略未通过.
        if(set.size() >= 1){
            log.info("【限流策略】 限流策略未通过，30s内，发过一条....");
            pushMessage.pushLog(submit, StrategyConstants.STRATEGY_ERROR_LIMIT);
            pushMessage.pushReport(submit, StrategyConstants.STRATEGY_ERROR_LIMIT);
            return false;
        }

        // 1小时三条短信
        //1. 获取当前系统时间

        //2. 获取1小时前的系统时间
        double oneHour = timeMillis - 60 * 60 * 1000;

        //3. 调用cache模块的rangebyscore命令,查询结果即可.
        set = cacheService.zRangeByScore(key, oneHour, timeMillis);

        //4. 结果长度大于等于3,限流策略未通过.
        if(set.size() >= 3){
            log.info("【限流策略】 限流策略未通过，一小时内，发过三条....");
            pushMessage.pushLog(submit, StrategyConstants.STRATEGY_ERROR_LIMIT);
            pushMessage.pushReport(submit, StrategyConstants.STRATEGY_ERROR_LIMIT);
            return false;
        }

        // 1天十条短信
        //1. 获取当前系统时间

        //2. 获取1天前的系统时间
        double oneDay = timeMillis - 60 * 60 * 24 * 1000;

        //3. 调用cache模块的rangebyscore命令,查询结果即可.
        set = cacheService.zRangeByScore(key, oneDay, timeMillis);

        //4. 结果长度大于等于10,限流策略未通过.
        if(set.size() >= 10){
            log.info("【限流策略】 限流策略未通过，一天内，发过十条....");
            pushMessage.pushLog(submit, StrategyConstants.STRATEGY_ERROR_LIMIT);
            pushMessage.pushReport(submit, StrategyConstants.STRATEGY_ERROR_LIMIT);
            return false;
        }

        log.info("【限流策略】 限流策略通过!!");
        return true;
    }
}
